/*
    This is a set of libraries to assist in OpenGl and Other Applications
    Copyright (C) 2008  The Modular Engine Team

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Lesser General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU Lesser General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#define HUDMODULE
#include "HUDModule.h"

namespace ModularEngine
{

	HUDModule::HUDModule()
	{
		mpFocusedElement = 0;
		mpHoveredElement = 0;
	}

	HUDModule::~HUDModule()
	{

	}

	int HUDModule::initialize()
	{
		// load all textures and stuff

		// set gl to the OpenglModule singleton
		gl = &ModularEngine::OpenglModule::getSingleton();

		return 1;
	}

	int HUDModule::run()
	{

		for( std::vector<HUDElement *>::iterator i = mvNewElements.begin(); i != mvNewElements.end(); i++ )
		{
			mvElements.push_back( (*i) );
		}

		mvNewElements.clear();

		mpHoveredElement = 0;
		for( std::vector<HUDElement *>::reverse_iterator i = mvElements.rbegin(); i != mvElements.rend(); i++ )
		{
			if( gl->pointInRect( WindowModule::getSingleton().getMouse(), (*i)->mvPosition, (*i)->mvDimensions ) && (*i)->mbVisible )
			{
				mpHoveredElement = *i;
				break;
			}
		}

		// Go through all loaded elements and draw them.
		for( std::vector<HUDElement *>::iterator i = mvElements.begin(); i != mvElements.end(); i++ )
		{
			if( (*i)->mbVisible )
				(*i)->draw();
		}

		return 1;
	}

	// TODO:
	// The following two functions don't work on the basis of item focus.
	// Basically the input is sent to everything which is not what we want.
	// This is mostly for testing purposes.

	void HUDModule::mouseInput( float X, float Y, UINT nDown )
	{
		// Go through the list backwards.  
		// The first one that has the mouse focus gets the input because the last one drawn appears on top
		for( std::vector<HUDElement *>::reverse_iterator i = mvElements.rbegin(); i != mvElements.rend(); i++ )
		{
			// If the mouse is in the boundaries, then the mouse is clicking in this element.
			if( gl->pointInRect( Vector2d( X, Y ),  (*i)->mvPosition, (*i)->mvDimensions ) && (*i)->mbVisible )
			{
				// Temporarily store current iterator in a pointer
				HUDElement *element = *i;
				// i+1 because... it just works.
				// Remove this iterator so that it can be pushed on top of the list
				mvElements.erase( (i+1).base() );
				// Push the element on top of the list
				mvElements.push_back( element );
				// Set mpFocusedElement to element
				mpFocusedElement = element;
				// Send the input
				element->mouseInput( Vector2d( X, Y ), nDown );
				return;
				// give focus
			}
		}
	}

	void HUDModule::keyboardInput( UINT nKey )
	{
		// Send keyboard input to the focused element
		//std::cout << "1Key: " << nKey << std::endl;
		if( mpFocusedElement )
			mpFocusedElement->keyboardInput( nKey );	
		//std::cout << "2Key: " << nKey << std::endl;
	}

	void HUDModule::addElement( HUDElement *pElement )
	{
		// Initialize the element and add it to the list
		pElement->initialize();
		// Add the element to the list
		mvNewElements.push_back( pElement );
		// Set the focused element as the one we just put on the list
		mpFocusedElement = pElement;
	}

	void HUDModule::setBaseColor( Vector3d vColor )
	{
		// Set the theme base color
		mvBaseColor = vColor;
	}

	void HUDModule::setTextColor( Vector3d vColor )
	{
		// Set the theme text color
		mvTextColor = vColor;
	}

	Vector3d HUDModule::getBaseColor()
	{
		// Return the theme's base color
		return mvBaseColor;
	}

	Vector3d HUDModule::getTextColor()
	{
		// Return the theme's text color
		return mvTextColor;
	}
}
